package j.framework.core.entity;

import j.data.ActionResult;
import j.framework.core.LoginUser;
import j.util.New;
import j.util.SpringBeans;
import j.util.StringUtils;
import j.util.jdbc.JdbcTemplate;

import java.lang.reflect.Method;
import java.util.Map;

/**
 * 实体触发器管理器
 * User: jason
 * Date: 2015/3/30 17:11
 */
public class EntityTriggerManager {
    private static EntityTriggerManager instance = new EntityTriggerManager();
    private EntityTriggerManager(){triggerMap = New.map();}
    public static EntityTriggerManager getInstance(){
        return instance;
    }

    private Map<String,EntityTrigger> triggerMap;

    /**
     * 根据触发器的实现类获取其实例
     * @param triggerClassName
     * @return
     */
    public static EntityTrigger getTrigger(String triggerClassName){
        if(StringUtils.isNullOrEmpty(triggerClassName)){
            return null;
        }
        EntityTrigger trigger = instance.triggerMap.get(triggerClassName);
        if(trigger!=null){
            return trigger;
        }
        synchronized (EntityTriggerManager.class){
            trigger = instance.triggerMap.get(triggerClassName);
            if(trigger == null){
                try {
                    trigger = (EntityTrigger)Class.forName(triggerClassName).newInstance();
                    instance.triggerMap.put(triggerClassName,trigger);
                }catch (Exception e){
                    throw new RuntimeException("触发器实现类["+triggerClassName+"]不存在！");
                }
            }
        }
        return trigger;
    }

    public static void invokeBeanTriggerMethod(int whenInvokeTag,EntityInvokeTrigger trigger,LoginUser user,JdbcTemplate jdbcTemplate,Map<String,Object> data,ActionResult ar){

        Class<?> clazz = null;
        try {
            clazz = Class.forName(trigger.getBeanClassName());
        }catch (ClassNotFoundException e){
            ar.add("err",String.format("bean[%s]不存在，请与开发人员联系！",trigger.getBeanClassName()));
            return;
        }
        Object bean = SpringBeans.getBean(clazz);
        if(bean!=null && StringUtils.isNotEmpty(trigger.getBeanMethodName())){
            try {
                Method m = bean.getClass().getDeclaredMethod(trigger.getBeanMethodName(), int.class,
                        LoginUser.class, JdbcTemplate.class, Map.class, ActionResult.class);
                Object beanInvokeResult = m.invoke(bean,whenInvokeTag, user, jdbcTemplate, data,ar);
                if(ar.hasErrors()){
                    //有错，则不再执行
                    return;
                }
                if(beanInvokeResult instanceof Boolean){
                    if(!((Boolean)beanInvokeResult)){
                        //触发器返回了false，不再执行
                        ar.add("trigger_err",String.format("触发器[%s]控制流程不再往下执行，开发人员未说明原因，请与开发人员联系!", trigger.getTriggerName()));
                    }
                }
            }catch (Exception e){
                e.printStackTrace();
                ar.add("trigger_err","调用触发器[" + trigger.getTriggerName() + "]时出错，" + e.getCause().getMessage());
            }
        }else{
            ar.add("trigger_err","触发器[" + trigger.getTriggerName() + "]配置错误。");
        }
    }
}
